﻿// -----------------------------------------------------------------------
// <copyright file="SubscriptionQueryResponse.cs" company="Zen Design Corp">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Zen.BlackBerry.Pap.Parser
{
	using System;
	using System.Collections.Generic;
	using System.Xml;
	using System.Xml.Serialization;
	using Zen.BlackBerry.Common;

	/// <summary>
	/// Represents the response from a subscription query request to the PPG.
	/// </summary>
	public class SubscriptionQueryResponse : PapMessage, IXmlSerializable
	{
		/// <summary>
		/// Gets or sets the push service id.
		/// </summary>
		/// <value>The push service id.</value>
		public string PushServiceId
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the results.
		/// </summary>
		/// <value>The results.</value>
		public SubscriptionQueryResult[] Results
		{
			get;
			set;
		}

		#region IXmlSerializable Members

		/// <summary>
		/// This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return null (Nothing in Visual Basic) from this method, and instead, if specifying a custom schema is required, apply the <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"/> to the class.
		/// </summary>
		/// <returns>
		/// An <see cref="T:System.Xml.Schema.XmlSchema"/> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"/> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"/> method.
		/// </returns>
		public System.Xml.Schema.XmlSchema GetSchema()
		{
			return null;
		}

		/// <summary>
		/// Generates an object from its XML representation.
		/// </summary>
		/// <param name="reader">The <see cref="T:System.Xml.XmlReader"/> stream from which the object is deserialized.</param>
		public void ReadXml(XmlReader reader)
		{
			PushServiceId = reader["pushservice-id"];

			if (reader.ReadToDescendant("subscriptionquery-result"))
			{
				List<SubscriptionQueryResult> results = new List<SubscriptionQueryResult>();
				do
				{
					using (XmlReader resultReader = reader.ReadSubtree())
					{
						if (resultReader.ReadToDescendant("subscriptionquery-detail"))
						{
							string code = resultReader["code"];
							string desc = resultReader["desc"];

							do
							{
								using (XmlReader detailReader = reader.ReadSubtree())
								{
									DateTime eventTime = reader.ReadRimTime("event-time");
									SubscriptionStatus status = reader.ReadEnum<SubscriptionStatus>("status", SubscriptionStatus.Unknown);

									if (detailReader.ReadToDescendant("address"))
									{
										do
										{
											SubscriptionQueryResult detail =
												new SubscriptionQueryResult
												{
													Code = code,
													Description = desc,
													EventTime = eventTime,
													Status = status,
													Address = reader["address-value"]
												};
											results.Add(detail);
										}
										while (detailReader.ReadToNextSibling("address"));
									}
								}
							}
							while (resultReader.ReadToNextSibling("subscriptionquery-detail"));
						}
					}
				}
				while (reader.ReadToNextSibling("subscriptionquery-result"));
				Results = results.ToArray();
			}
		}

		/// <summary>
		/// Converts an object into its XML representation.
		/// </summary>
		/// <param name="writer">The <see cref="T:System.Xml.XmlWriter"/> stream to which the object is serialized.</param>
		public void WriteXml(XmlWriter writer)
		{
			throw new NotImplementedException();
		}

		#endregion
	}

	/// <summary>
	/// Represents a result within a subscription query response.
	/// </summary>
	public class SubscriptionQueryResult
	{
		/// <summary>
		/// Gets or sets the code.
		/// </summary>
		/// <value>The code.</value>
		public string Code
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the description.
		/// </summary>
		/// <value>The description.</value>
		public string Description
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the event time.
		/// </summary>
		/// <value>The event time.</value>
		public DateTime EventTime
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the status.
		/// </summary>
		/// <value>The status.</value>
		public SubscriptionStatus Status
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the address.
		/// </summary>
		/// <value>The address.</value>
		public string Address
		{
			get;
			set;
		}
	}

	/// <summary>
	/// 
	/// </summary>
	public enum SubscriptionStatus
	{
		/// <summary>
		/// An active status.
		/// </summary>
		[XmlEnum("active")]
		Active = 0,

		/// <summary>
		/// A suspended status.
		/// </summary>
		[XmlEnum("suspended")]
		Suspended = 1,

		/// <summary>
		/// An unsubscribed/inactive status.
		/// </summary>
		[XmlEnum("cancelled")]
		Unsubscribed = 2,

		/// <summary>
		/// An unknown/does-not-exist status.
		/// </summary>
		[XmlEnum("unknown")]
		Unknown = 3,
	}
}
